package com.ws.universal.tools.utils;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.LocationManager;
import android.os.Build;
import android.provider.Settings;
import android.util.Pair;

import androidx.annotation.RequiresApi;
import androidx.core.content.PermissionChecker;

import com.ws.universal.tools.permission.AppActivityTarget;
import com.ws.universal.tools.permission.PermissionListener;
import com.ws.universal.tools.permission.Rationale;
import com.ws.universal.tools.permission.RationaleListener;
import com.ws.universal.tools.permission.SettingExecutor;
import com.ws.universal.tools.permission.SettingService;
import com.ws.universal.tools.permission.WsAndPermission;
import com.ws.universal.tools.utils.constant.PermissionConstants;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/**
 * @author:ws
 * @date: 2021/7/29 15:57
 * @desc
 */
public final class PermissionUtils {

    //onActivityResult code
    public static final int REQUEST_CODE_SETTING = 300;
    // 检查是否获得了权限（Android6.0运行时权限）
    //权限没有获得
    private static final int REQUEST_CODE_PERMISSION_SINGLE = 100;
    public static PermissionUtils permissionTools;
    /**
     * 读写权限示例 可外部定义
     */
    public static String[] Permission_File = {"android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE"

    };
    /**
     * 需要的所有权限
     */
    public static String[] Permission_All = {"android.permission.CAMERA", "android.permission.WRITE_EXTERNAL_STORAGE",
            "android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION",
            "android.permission.READ_PHONE_STATE"

    };
    /**
     * 定位权限示例 可外部定义
     */
    public static String[] Permission_Location = {"android.permission.ACCESS_COARSE_LOCATION", "android.permission.ACCESS_FINE_LOCATION"

    };
    /**
     * 设备权限示例 可外部定义
     */
    public static String Permission_ReadPhone = "android.permission.CALL_PHONE";
    public static String[] Permission_ReadAndWritePhone = {"android.permission.READ_EXTERNAL_STORAGE", "android.permission.WRITE_EXTERNAL_STORAGE"

    };
    private static Context context;
    //当权限被禁止弹出提示时
    private SettingService mSettingService;

    public static void initial(Context con) {
        context = con;
    }

    public static PermissionUtils getInstance() {
        if (permissionTools == null) {
            permissionTools = new PermissionUtils();
        }
        return permissionTools;
    }

    public static List<String> getPermissions() {
        return getPermissions(Utils.getApp().getPackageName());
    }

    public static List<String> getPermissions(final String packageName) {
        PackageManager pm = Utils.getApp().getPackageManager();
        try {
            String[] permissions = pm.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS).requestedPermissions;
            if (permissions == null) return Collections.emptyList();
            return Arrays.asList(permissions);
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
            return Collections.emptyList();
        }
    }

    private static Pair<List<String>, List<String>> getRequestAndDeniedPermissions(final String... permissionsParam) {
        List<String> requestPermissions = new ArrayList<>();
        List<String> deniedPermissions = new ArrayList<>();
        List<String> appPermissions = getPermissions();
        for (String param : permissionsParam) {
            boolean isIncludeInManifest = false;
            String[] permissions = PermissionConstants.getPermissions(param);
            for (String permission : permissions) {
                if (appPermissions.contains(permission)) {
                    requestPermissions.add(permission);
                    isIncludeInManifest = true;
                }
            }
            if (!isIncludeInManifest) {
                deniedPermissions.add(param);
                LogcatUtils.e("PermissionUtils", "U should add the permission of " + param + " in manifest.");
            }
        }
        return Pair.create(requestPermissions, deniedPermissions);
    }

    @SuppressLint("WrongConstant")
    //Permission.READ_PHONE_STATE
    public static boolean hasPermissions(Context context, String permission) {
        if (PermissionChecker.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED) {
            return true;
        }
        return false;
    }

    public static boolean hasPermissions(final String... permissions) {
        Pair<List<String>, List<String>> requestAndDeniedPermissions = getRequestAndDeniedPermissions(permissions);
        List<String> deniedPermissions = requestAndDeniedPermissions.second;
        if (!deniedPermissions.isEmpty()) {
            return false;
        }
        List<String> requestPermissions = requestAndDeniedPermissions.first;
        for (String permission : requestPermissions) {
            if (!hasPermissions(permission)) {
                return false;
            }
        }
        return true;
    }

    @RequiresApi(api = Build.VERSION_CODES.M)
    public static boolean isGrantedDrawOverlays() {
        return Settings.canDrawOverlays(Utils.getApp());
    }

    public void CheckPermissions(PermissionListener permissionListener, int requestCode, String... permissions) {
        // 申请单个权限。
        WsAndPermission.with(context).requestCode(requestCode).permission(permissions).callback(permissionListener)
                // rationale作用是：用户拒绝一次权限，再次申请时先征求用户同意，再打开授权对话框；
                // 这样避免用户勾选不再提示，导致以后无法申请权限。
                // 你也可以不设置。
                .rationale(new RationaleListener() {
                    @Override
                    public void showRequestPermissionRationale(int requestCode, Rationale rationale) {
                        // 这里的对话框可以自定义，只要调用rationale.resume()就可以继续申请。
                        rationale.resume();
                    }
                }).start();
    }

    /**
     * 手机是否开启位置服务，如果没有开启那么所有app将不能使用定位功能
     */
    public boolean isLocServiceEnable(Context context) {
        LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
        boolean gps = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
        boolean network = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        if (gps || network) {
            return true;
        }
        return false;
    }

    public SettingService getSettingService(int REQUEST_CODE_SETTING, Activity activity) {
        if (mSettingService == null) {
            mSettingService = new SettingExecutor(new AppActivityTarget(activity), REQUEST_CODE_SETTING);
        }
        return mSettingService;
    }

}
